from os import read
from threading import Lock
import time
import requests
import config
import json
from database import tables
import re
from utils.autorun import AutoRunMethod, AutoRunMutiMethod
from utils import method


# @AutoRunMethod(num_of_run=1, delay=3600*24, wait=True, test=True)
def update_car_code():  # 该数据只需要爬一次即可，并且需要等待数据爬取完成方可继续运行
    DB = config.DB
    url = 'https://car.autohome.com.cn/javascript/NewSpecCompare.js'
    res = requests.get(url)  # 主要的费时操作
    res.encoding = 'GB18030'
    res = res.text.strip()  # 删除首尾空格。
    res = res[21:-1]  # 删除首尾字母
    json_date = json.loads(res)

    with DB.inserter(tables.carName, log=True) as inserter:  # 另一处费时操作
        for brand in json_date:  # 品牌
            for manufacturer in brand['List']:  # 厂商
                for CarSeries in manufacturer['List']:  # 车系
                    insert_data = {
                        tables.carName.car_name: CarSeries["N"],
                        tables.carName.car_id: CarSeries['I'],
                        tables.carName.carP_name: brand["N"],
                        tables.carName.carP_id: brand['I'],
                        tables.carName.carCompany_id: manufacturer["I"],
                        tables.carName.carCompany_name: manufacturer["N"],
                    }
                    inserter.insert_table(insert_data)


# @AutoRunMethod(num_of_run=1, delay=3600*24, wait=True)
def update_province_code():
    DB = config.DB
    url = 'https://www.autohome.com.cn/hangye/dataquery/?type=2#pvareaid=6838334'
    res = requests.get(url)
    partten = re.compile('var allAreaJson =(.*?);')  # 正则表达式取
    res_ = re.findall(partten, res.text)[0]
    json_date = json.loads(res_)
    with DB.inserter(tables.province) as inserter:
        for daqu in json_date:
            it = json_date[daqu]
            for itt in it:
                insert_data = {
                    tables.province.area_name: itt["area_name"],
                    tables.province.province_name: itt["province_name"],
                    tables.province.province_id: itt["province_id"],
                }
                inserter.insert_table(insert_data)


# @AutoRunMutiMethod(num_of_run=1, delay=3600*24, wait=True, max_thread=25, test=True)
def update_car_sell():
    DB = config.DB
    url = 'https://www.autohome.com.cn/Channel2/Conjunction/ashx/GetDataReportCarKanban.ashx'

    def kernal(it):
        print(f"{it} is work!!!")
        param_dict = {
            'start': "2016-01-01",
            'end': "2021-06-01",
            'seriesnames': [it],
            'brandids': [],
            'factoryids': [],
            'energytypes': [],
            'seriesplaces': [],
            'carlevelnames': [],
            'displacementtypes': [],
            'areanames': [],
            'provinceids': [],
            'citylevel': [],
            'type': 2
        }
        res = requests.post(url, data=json.dumps(
            param_dict, ensure_ascii=False).encode('utf8'))
        try:
            json_date = json.loads(res.text)['cheqikanbanOpt'][it]
            with DB.inserter(tables.carSell) as inserter:
                for item in json_date:
                    insert_data = {
                        tables.carSell.car_number: item["TotalScore"],
                        tables.carSell.sell_time: item["dt"],
                        tables.carSell.car_name: it,
                    }
                    inserter.insert_table(insert_data)
        except Exception as e:
            return
        print(f"{it} is done!!!")

    yield kernal

    data = DB.select_table(tables.carName, [tables.carName.car_name])
    yield from (it[0] for it in data)


# @AutoRunMutiMethod(num_of_run=1, delay=1, wait=True, max_thread=10, test=True)
def update_type_number():
    DB = config.DB

    url = 'https://www.autohome.com.cn/Channel2/Conjunction/ashx/GetDataReportQuery.ashx'
    head = {
        'origin': 'https://www.autohome.com.cn',
        'referer': 'https://www.autohome.com.cn/hangye/dataquery/',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
    }

    EnergyEcharts = ["燃油", "新能源"]
    FactoryEcharts = ["自主", "合资"]
    LevelEcharts = ["轿车", "SUV", "MPV"]
    PriceEcharts = ["6万以下", "6-9万", "9-12万", "12-15万", "15-20万",
                    "20-30万", "30-50万", "50-100万", "100万以上"]
    DisplacementEcharts = ["1.0L及以下", "1.1-1.6L", "1.7-2.0L",
                           "2.1-2.5L", "2.6-3.0L", "3.1-4.0L", "4.0L以上"]

    def kernal(args):
        province_id, Energy, Factory, Level, Price, Displacement = args
        print(args, 'start!!')
        province_id = province_id[0]
        param_dict = {
            "start": "2016-01-01",
            "end": "2021-06-01",
            "seriesnames": [],
            "brandids": [],
            "factoryids": [],
            "energytypes": [Energy],
            "newenergytypes": [],
            "seriesplaces": [Factory],
            "carleveltypes": [Level],
            "carlevelnames": [],
            "displacementtypes": [Displacement],
            "pricetypes": [Price],
            "areanames": [],
            "provinceids": [str(province_id)],
            "citylevel": [],
            "type": "2"
        }
        param = json.dumps(param_dict, ensure_ascii=False)
        read_data = ''
        cnt = 10

        while read_data == '' and cnt > 0:
            try:
                res = requests.post(url, headers=head, data=param.encode(
                    'utf-8'), proxies=config.proxies)
                read_data = res.text
            except requests.exceptions.ProxyError:
                time.sleep(0.5)
            except Exception as e:
                print(type(e), ':', e)
            finally:
                cnt -= 1

        if cnt == 0 or read_data == '':
            print(args, '失败!!')
            return

        try:
            json_date = json.loads(read_data)
            EnergyEcharts_date = json_date["EnergyEcharts"][Energy]
            with DB.inserter(tables.Sellall, log=True) as inserter:
                for tem in EnergyEcharts_date:
                    insert_data = {
                        tables.Sellall.EnergyEcharts: Energy,
                        tables.Sellall.DisplacementEcharts: Displacement,
                        tables.Sellall.FactoryEcharts: Factory,
                        tables.Sellall.LevelEcharts: Level,
                        tables.Sellall.PriceEcharts: Price,
                        tables.Sellall.time: tem["dt"],
                        tables.Sellall.province_id: province_id,
                        tables.Sellall.number: tem["TotalScore"],
                    }
                    inserter.insert_table(insert_data)
            print(args, '成功!!')
        except Exception as e:
            if isinstance(e, json.decoder.JSONDecodeError):
                print(read_data, '\n\n')
                print(args, '失败!!')
                return
            else:
                print(type(e), ':', e)
                print(read_data, '\n\n')
                print(args, '成功!!')

    yield kernal

    # 540000
    data = DB.select_table(tables.province, [tables.province.province_id])
    for attrs in method.enumeration(data, EnergyEcharts, FactoryEcharts, LevelEcharts, PriceEcharts, DisplacementEcharts):
        if attrs[0][0] >= 540000:
            yield attrs


# @AutoRunMutiMethod(num_of_run=1, delay=1, wait=True, max_thread=3, test=True)
def getCarType():
    DB = config.DB
    host = 'https://www.autohome.com.cn/%s/'

    type_list = {
        '微型车': 'a00',
        '小型车': 'a0',
        '紧凑型车': 'a',
        '中型车': 'b',
        '中大型车': 'c',
        '大型车': 'd',
        'SUV': 'suv',
        'MPV': 'mpv',
        '跑车': 's',
        '皮卡': 'p',
        '微面': 'mb',
        '清客': 'qk',
    }
    partten = re.compile('">([^<\s].*)</a>.*</h4><div>指导价')

    def kernel(arg):
        type_name, url = arg
        print(type_name, url)
        res = requests.get(host % url)
        res.encoding = 'GB18030'
        data = res.text
        if data == '':
            print(type_name, '失败!')
            return

        data = re.findall(partten, data)
        with DB.inserter(tables.carType) as inserter:
            for it in data:
                insert_data = {
                    tables.carType.car_name: it,
                    tables.carType.car_type: type_name,
                }
                inserter.insert_table(insert_data)
            print(type_name, len(data))

    yield kernel

    for a, b in type_list.items():
        yield (a, b)


# @AutoRunMethod(num_of_run=1, delay=3600*24, wait=True, test=True)
def UpdateDatabase():
    DB = config.DB
    DB.clear_table(tables.SellAllWithProvince)
    data = DB.select_table([tables.province, tables.Sellall], '*')
    with DB.inserter(tables.SellAllWithProvince) as inserter:
        for now, it in enumerate(data):
            inserter.insert_table(*it)
            if now % 100 == 0:
                print(f'\r{now}      ', end='')